package com.jh.netty.server;

import io.netty.bootstrap.ServerBootstrap;
import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelOption;
import io.netty.channel.EventLoopGroup;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.nio.NioServerSocketChannel;

public class ChatServer {
    // NIO线程组，Reactor线程组，一个用于接受客户端的请求，另一个用于进行SocketChannel的操作
    private final EventLoopGroup bossGroup = new NioEventLoopGroup();
    private final EventLoopGroup workerGroup = new NioEventLoopGroup();

    private final int port; //服务器端端口号

    public ChatServer(int port) {
        this.port = port;
    }

    public void run() throws Exception {
        try {
            // 用于NIO服务端启动的辅助类
            ServerBootstrap b = new ServerBootstrap();
            b.group(bossGroup, workerGroup)
                    .channel(NioServerSocketChannel.class)
                    // 这个childHandler参数设置的是我们自己定义的一个通道处理ChildChannelHandler
                    .childHandler(new ServerInitializer())
                    .option(ChannelOption.SO_BACKLOG, 128)
                    .childOption(ChannelOption.SO_KEEPALIVE, true);

            System.out.println("Netty Chat Server 启 动 ......");
            // 绑定端口，同步等待成功，一直等待到绑定端口成功，返回一个ChannelFuture,类似JDK中的java.util.concurrent.Future
            // 用于异步的通知会调
            ChannelFuture f = b.bind(port).sync();
            // 进行阻塞，等待服务器链路关闭，就退出
            f.channel().closeFuture().sync();
        } finally {
            // 优雅退出，释放线程资源
            workerGroup.shutdownGracefully();
            bossGroup.shutdownGracefully();
            System.out.println("Netty Chat Server 关闭......");
        }
    }

    public static void main(String[] args) throws Exception {
        new ChatServer(8080).run();
    }
}
